home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
GraphicViewers
/
pCD
/
Source
/
hpcdtoppm.0.4
/
format.c.ORIG
< prev
next >
Wrap
Text File
|
1993-03-23
|
8KB
|
354 lines
/* hpcdtoppm (Hadmut's pcdtoppm) v0.4
* Copyright (c) 1992, 1993 by Hadmut Danisch (danisch@ira.uka.de).
* Permission to use and distribute this software and its
* documentation for noncommercial use and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation. It is not allowed to sell this software in
* any way. This software is not public domain.
*/
#include "hpcdtoppm.h"
struct pcdquad { uBYTE len,highseq,lowseq,key;};
struct pcdhqt { uBYTE entries; struct pcdquad entry[256];};
struct myhqt { unsigned long seq,mask,len; uBYTE key; };
#define E ((unsigned long) 1)
static void readhqtsub(quelle,ziel,anzahl)
struct pcdhqt *quelle;
struct myhqt *ziel;
int *anzahl;
{int i;
struct pcdquad *sub;
struct myhqt *help;
*anzahl=(quelle->entries)+1;
for(i=0;i<*anzahl;i++)
{sub = (struct pcdquad *)(((uBYTE *)quelle)+1+i*sizeof(*sub));
help=ziel+i;
help->seq = (((unsigned long) sub->highseq) << 24) |(((unsigned long) sub->lowseq) << 16);
help->len = ((unsigned long) sub->len) +1;
help->key = sub->key;
#ifdef DEBUGhuff
fprintf(stderr," Anz: %d A1: %08x A2: %08x X:%02x %02x %02x %02x Seq: %08x Laenge: %d %d\n",
*anzahl,sbuffer,sub,((uBYTE *)sub)[0],((uBYTE *)sub)[1],((uBYTE *)sub)[2],((uBYTE *)sub)[3],
help->seq,help->len,sizeof(uBYTE));
#endif
if(help->len > 16) error(E_HUFF);
help->mask = ~ ( (E << (32-help->len)) -1);
}
#ifdef DEBUG
for(i=0;i<*anzahl;i++)
{help=ziel+i;
fprintf(stderr,"H: %3d %08lx & %08lx (%2d) = %02x = %5d %8x\n",
i, help->seq,help->mask,help->len,help->key,(signed char)help->key,
help->seq & (~help->mask));
}
#endif
}
#undef E
static struct myhqt myhuff0[256],myhuff1[256],myhuff2[256];
static int myhufflen0=0,myhufflen1=0,myhufflen2=0;
void readhqt(w,h,n)
dim w,h;
int n;
{
uBYTE *ptr;
melde("readhqt\n");
EREADBUF;
ptr = sbuffer;
readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0);
if(n<2) return;
ptr+= 1 + 4* myhufflen0;
readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);
if(n<3) return;
ptr+= 1 + 4* myhufflen1;
readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);
}
#ifdef FASTHUFF
static struct myhqt *HTAB0[0x10000],*HTAB1[0x10000],*HTAB2[0x10000];
static void inithuff(hlen,ptr,TAB)
int hlen;
struct myhqt *ptr,*TAB[];
{int i,n;
long seq,len;
struct myhqt *help;
for(i=0;i<0x10000;i++) TAB[i]=0;
for(n=0;n<hlen;n++)
{help=ptr+n;
seq=(help->seq)>>16;
len=help->len;
for(i=0;i<(1<<(16-len));i++)
TAB[seq | i] = help;
}
}
#endif
static char *pn[]={"Luma Channel","Chroma1 Channel","Chroma2 Channel"};
void decode(w,h,f,f1,f2,autosync)
dim w,h;
implane *f,*f1,*f2;
int autosync;
{int htlen,sum,do_inform,part;
unsigned long sreg,maxwidth;
unsigned int inh,n,zeile,segment,ident;
struct myhqt *hp;
uBYTE *nptr;
uBYTE *lptr;
#define nextbuf { nptr=sbuffer; EREADBUF; }
#define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
#define shiftout(n){ sreg<<=n; inh-=n; \
while (inh<=24) \
{checkbuf; \
sreg |= ((unsigned long)(*(nptr++)))<<(24-inh);\
inh+=8;\
}\
}
#define issync ((sreg & 0xffffff00) == 0xfffffe00)
#define brutesync ((sreg & 0x00fff000) == 0x00fff000)
#define seeksync { while (!brutesync) shiftout(8); while (!issync) shiftout(1);}
#ifdef FASTHUFF
struct myhqt **HTAB;
HTAB=0;
inithuff(myhufflen0,myhuff0,HTAB0);
inithuff(myhufflen1,myhuff1,HTAB1);
inithuff(myhufflen2,myhuff2,HTAB2);
#define SETHUFF0 HTAB=HTAB0;
#define SETHUFF1 HTAB=HTAB1;
#define SETHUFF2 HTAB=HTAB2;
#define FINDHUFF(x) {x=HTAB[sreg>>16];}
#else
int i;
struct myhqt *htptr;
htptr=0;
#define SETHUFF0 { htlen=myhufflen0 ; htptr = myhuff0 ; }
#define SETHUFF1 { htlen=myhufflen1 ; htptr = myhuff1 ; }
#define SETHUFF2 { htlen=myhufflen2 ; htptr = myhuff2 ; }
#define FINDHUFF(x) {for(i=0, x=htptr;(i<htlen) && ((sreg & x ->mask)!= x->seq); i++,x++); \
if(i>=htlen) x=0;}
#endif
melde("decode\n");
if( f && ((! f->im) || ( f->iheight < h ) || (f->iwidth<w ))) error(E_INTERN);
if( f1 && ((!f1->im) || (f1->iheight < h/2) || (f1->iwidth<w/2))) error(E_INTERN);
if( f2 && ((!f2->im) || (f2->iheight < h/2) || (f2->iwidth<w/2))) error(E_INTERN);
htlen=sreg=maxwidth=0;
zeile=0;
nextbuf;
inh=32;
lptr=0;
part=do_inform=0;
shiftout(16);
shiftout(16);
if(autosync) seeksync;
n=0;
for(;;)
{
if (issync)
{shiftout(24);
ident=sreg>>16;
shiftout(16);
zeile=(ident>>1) & 0x1fff;
segment=ident>>14;
if(do_inform) {fprintf(stderr,"Synchron mark found Line %d\n",zeile);do_inform=0;}
#ifdef DEBUG
fprintf(stderr,"Id %4x Zeile: %6d Seg %3d Pix bisher: %5d Position: %8lx+%5lx=%8x\n",
ident,zeile,segment,n,bufpos,nptr-sbuffer,bufpos+nptr-sbuffer);
#endif
if(lptr && (n!=maxwidth))
{if(!do_rep)error(E_SEQ1);
else fprintf(stderr,"Line %d in %s : wrong length of last line (%d)\n",zeile,pn[part],n);
}
n=0;
if(zeile==h) {RPRINT; return; }
if(zeile >h) error(E_SEQ2);
switch(segment)
{
case 0: if((!f) && autosync) {seeksync; break;}
if(!f) error(E_SEQ7);
lptr=f->im + zeile*f->mwidth;
maxwidth=f->iwidth;
SETHUFF0;
part=0;
break;
case 2: if((!f1) && autosync) {seeksync; break;}
if(!f1) return;
if(!f1) error(E_SEQ7);
lptr=f1->im + (zeile>>1)*f1->mwidth;
maxwidth=f1->iwidth;
SETHUFF1;
part=1;
break;
case 3: if((!f2) && autosync) {seeksync; break;}
if(!f2) return;
if(!f2) error(E_SEQ7);
lptr=f2->im + (zeile>>1)*f2->mwidth;
maxwidth=f2->iwidth;
SETHUFF2;
part=2;
break;
default:error(E_SEQ3);
}
}
else
{
if(!lptr) error(E_SEQ6);
if(n>maxwidth)
{
#ifdef DEBUG
fprintf(stderr,"Register: %08lx Pos: %08lx\n",sreg,bufpos+nptr-sbuffer);
#endif
if (!do_rep) error(E_SEQ4);
else { fprintf(stderr,"Missing synchron mark in %s line %d\n",pn[part],zeile);
seeksync;
do_inform=1;
n=maxwidth;
}
}
else
{FINDHUFF(hp);
if(!hp) error(E_SEQ5);
sum=((int)(*lptr)) + ((sBYTE)hp->key);
NORM(sum);
*(lptr++) = sum;
n++;
shiftout(hp->len);
}
}
}
#undef nextbuf
#undef checkbuf
#undef shiftout
#undef issync
#undef seeksync
}
enum ERRORS readplain(fpcd,w,h,l,c1,c2)
FILE *fpcd;
dim w,h;
implane *l,*c1,*c2;
{dim i;
uBYTE *pl=0,*pc1=0,*pc2=0;
melde("readplain\n");
if(l)
{ if ((l->mwidth<w) || (l->mheight<h) || (!l->im)) error(E_INTERN);
l->iwidth=w;
l->iheight=h;
pl=l->im;
}
if(c1)
{ if ((c1->mwidth<w/2) || (c1->mheight<h/2) || (!c1->im)) error(E_INTERN);
c1->iwidth=w/2;
c1->iheight=h/2;
pc1=c1->im;
}
if(c2)
{ if ((c2->mwidth<w/2) || (c2->mheight<h/2) || (!c2->im)) error(E_INTERN);
c2->iwidth=w/2;
c2->iheight=h/2;
pc2=c2->im;
}
for(i=0;i<h/2;i++)
{
if(pl)
{
if(fread(pl,w,1,fpcd)<1) return(E_READ);
pl+= l->mwidth;
if(fread(pl,w,1,fpcd)<1) return(E_READ);
pl+= l->mwidth;
}
else SKIPr(2*w);
if(pc1)
{ if(fread(pc1,w/2,1,fpcd)<1) return(E_READ);
pc1+= c1->mwidth;
}
else SKIPr(w/2);
if(pc2)
{ if(fread(pc2,w/2,1,fpcd)<1) return(E_READ);
pc2+= c2->mwidth;
}
else SKIPr(w/2);
}
RPRINT;
return E_NONE;
}